﻿using System;
using System.Configuration;
using NHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;

namespace Persistence
{
    /// <summary>
    /// Helper class to handle nHibernate Session creation and access..
    /// </summary>
    public class NHibernateSessionHelper
    {
        private static ISessionFactory _sessionFactory = null;

        /// <summary>
        /// Returns current nHibernate Session
        /// If never created before, it uses a SessionFactory to create one..
        /// </summary>
        /// <returns></returns>
        public static ISession GetSession()
        {
            ISessionFactory sessionFactory = null;
            ISession session = null;
            try
            {
                sessionFactory = GetSessionFactory();
                session = sessionFactory.OpenSession();
                if (session == null)
                {
                    throw new InvalidOperationException("Cannot open nHibernate session.");
                }
            }
            catch (Exception)
            {
                throw;
            }
            return session;
        }

        /// <summary>
        /// Creates (and returns) a nHibernate Session, including database connection and mappings
        /// </summary>
        /// <returns></returns>
        private static ISessionFactory GetSessionFactory()
        {
            try
            {
                if (_sessionFactory == null)
                {
                    #region > Fluent Configuration
                    var connString = ConfigurationManager.AppSettings["connectionString"];

                    const string mappingsDomain = "Persistencia"; //Project name (assembly) where mappings classes are located..
                    var asm = System.Reflection.Assembly.Load(mappingsDomain);

                    _sessionFactory = Fluently.Configure()
                        .Database(MsSqlConfiguration.MsSql2008.ConnectionString(connString).ShowSql())
                        .Mappings(m => m.FluentMappings.AddFromAssembly(asm))
                        .BuildSessionFactory();
                    #endregion

                    if (_sessionFactory == null)
                        throw new InvalidOperationException("Could not build SessionFactory");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return _sessionFactory;
        }
    }
}
